//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// NOTE: stubs are being used - this isn't done

#include <windows.h>
#include <oal.h>
#include <bsp.h>

//-----------------------------------------------------------------------------
extern void EnterStandby(DWORD dwCodeAddr);
extern void Standby(void);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//the length of StandByCode should be 4 bytes step
const DWORD DDR_MemCmd[4]=
{
	0x40170000, 0x00110000, 0x40170000, 0x60170000
};
const DWORD SDRAM_MemCmd[4]=
{
	0xC0170000, 0x80110000, 0xC0170000, 0xE0170000
};

void Power_Off()
{
    PULONG pL2_Ram = NULL;
    PULONG pDramCtrl = NULL;
    const DWORD* pdwStandbyCode;
	DWORD i,j;
    
    pL2_Ram = (PULONG)OALPAtoUA(AK_BASE_REG_PA_L2RAM);
    pDramCtrl = (PULONG)OALPAtoUA(AK_BASE_REG_PA_DMA);

	// copy standby code to l2ram
	pdwStandbyCode=(DWORD*)Standby;
	for(i=0; i<(512/4-4); i++)
	{
		if( (0x12345678==pdwStandbyCode[i])
			&& (0x23456789==pdwStandbyCode[i+1])
			&& (0x98765432==pdwStandbyCode[i+2]) 
			&& (0x87654321==pdwStandbyCode[i+3]))
		{
			break;
		}
		pL2_Ram[i]=pdwStandbyCode[i];
	}
	if(i==(512/4-4))
	{
    	RETAILMSG(1, (TEXT("!!!Can't find valid standby code!!!\n")));
	}
	else
	{
		// copy mem cmd
		if((1<<26)&pDramCtrl[1])
		{
			pdwStandbyCode=DDR_MemCmd;
		}
		else
		{
			pdwStandbyCode=SDRAM_MemCmd;
		}
		for(j=0; j<4; j++, i++)
		{
			pL2_Ram[i]=pdwStandbyCode[j];
		}
/*
for(j=0; j<i; j++)
{
RETAILMSG(1, (TEXT("0x%x\r\n"), pL2_Ram[j]));
}
*/
        //enter standby mode
        RETAILMSG(1, (TEXT("++ OEMPowerOff\n")));
	    EnterStandby((DWORD)pL2_Ram);
        RETAILMSG(1, (TEXT("-- OEMPowerOff\n")));
	}
     
}


